Skip to content

Jenkins Pipeline As Code

image-20230404072431734

目录

[toc]

本节实战

实战名称
💘 实战:第一条Pipeline-2023.4.7(测试成功)
💘 实战:脚本式语法测试-2023.4.7(测试成功)
💘 实战:测试脚本式语法-2023.4.7(测试成功)
💘 实战:声明式语法嵌入脚本式语法-2023.4.7(测试成功)
💘 实战:利用片段生成器生成执行shell命令代码-2023.4.7(测试成功)
💘 实战:单引号和双引号的区别-2023.4.7(测试成功)
💘 实践:使用jenkins的内置变量来显示构建名及构建分支-2023.3.23(测试成功)
💘 实践:输出全局变量BUILD_ID和BUILD_URL(测试成功)-2023.4.8
💘 实践:agent配置的几种方法(测试成功)-2023.4.8
💘 实践:post{}测试(测试成功)-2023.4.8
💘 实践:变量测试(测试成功)-2023.4.8
💘 实践:options测试(测试成功)-2023.4.8
💘 实践:配置流水线跳过默认代码检出功能-2023.6.26(测试成功)
💘 实践:parameters测试(测试成功)-2023.4.8
💘 实践:input测试(测试成功)-2023.4.8
💘 实践:when测试(测试成功)-2023.4.8
💘 实践:parallel测试(测试成功)-2023.4.10
💘 实战:groovy字符串测试-2023.4.10(测试成功)
💘 实战:groovy列表测试-2023.4.10(测试成功)
💘 实战:groovy if语句测试-2023.4.10(测试成功)
💘 实战:groovy switch语句测试-2023.4.10(测试成功)
💘 实战:groovy for语句测试-2023.4.10(测试成功)
💘 实战:groovy while语句测试-2023.4.10(测试成功)
💘 实战:groovy 异常处理测试-2023.4.10(测试成功)
💘 实战:groovy 函数测试-2023.4.10(测试成功)
💘 实践:Jenkins共享库实践(测试成功)-2023.4.11

一、pipeline

1、什么是Pipeline

image-20230407065712398

1、Pipeline简介

image-20230406074003731

  • Pipeline是Jenkins 2.0版本推出的核心功能;
  • Pipeline可以实现以代码的方式定义工作流程;
  • 商业价值:
    • 组织级别及团队间工作流复用;
    • 便于Pipeline开发与维护;
    • 减少人工Web页面操作;

如果装了中文插件后,这里可能显示为流水线

image-20230406073610528

Jenkins的核心是Pipeline(流水线项目),实现了Pipeline As Code。即我们将构建部署测试等步骤全部以代码的形式写到Jenkinsfile中。Jenkins在运行Pipeline任务的时候会按照Jenkinsfile中定义的代码顺序执行。写Jenkinsfile是一项很重的工作,如果稍不注意很容易造成Jenkins的流水线任务失败。Jenkinsfile类似于Dockerfile,具有一套特定的语法。

在2年前, 18年的时候,我们一直在使用自由风格类型的项目。 每个项目中会有代码库的参数信息。 直到有一天项目的代码块从SVN迁移到了GITLAB,即需要我来操作修改Jenkins作业中的代码库URL信息。 修改的过程不复杂,即在web页面中修改然后保存即可。看似简单的过程,但是有大量的流水线作业,基本上一上午就在点点点。(操作简单,重复性动作太多了)

后来了解到Jenkins的核心特性Pipeline, 用代码的方式描述流水线。 这样我就可以维护多个Jenkinsfile来对应不同类型的项目了。 也实现了一部分项目使用统一的一个Jenkinsfile模板来管理

2、Pipeline组成

image-20230406074604526

  • Jenkinsfile:描述Pipeline的代码文件
  • Agent:Pipeline的运行节点
  • Stage:Pipeline的阶段

Jenkinsfile:是实现Pipeline as Code的核心功能。 该文件用于描述流水线的过程。

Agent: (是否还记得上次课程添加的JenkinsAgent节点)执行Pipeline的实际节点。

在Jenkins pipeline中,一条流水线是由多个阶段组成的,每个阶段一个stage。例如:构建、测试、部署等等。

3、第一条Pipeline

==💘 实战:第一条Pipeline-2023.4.7(测试成功)==

image-20230407065143482

  • 安装Pipeline插件;
  • 创建Pipeline类型项目;
  • 项目设置,编写Pipeline;
  • 构建项目;

让我们开始编写第一条Pipeline吧: 第一条流水线不用太复杂,主要是便于理解流水线的结构。

groovy
pipeline {agent anystages{stage("hello"){steps{echo "Hello Jenkins"}}}}

安装Pipeline插件

在创建Pipeline类型的作业的时候,需要提前安装好pipeline插件,不然可能会出现找不到pipeline类型的作业。

进入插件管理, 搜索关键字"pipeline"。安装后重启一下。

tstmp_20230407065322

创建Pipeline类型的作业,然后用我们上面编写好的代码运行一下吧。

image-20230407065558986

image-20230407065527767

2、Jenkinsfile语法

Jenkinsfile的基本概念和Jenkins Pipeline的语法类型。

1、Jenkinsfile是什么?

image-20230407071153536

  • 功能: 描述Jenkins Pipeline (Jenkinsfile主要是用来存储用于描述Pipeline的代码。 我们将pipeline的描述代码保存到Jenkinsfile这个文件中。 )

  • 存放方式:

    • 将Jenkinsfile 存放在项目设置(原生支持); (虽然实现了PipelineAsCode但是多个作业管理起来不太方便。)

    • 将Jenkinsfile 存放在Git系统(原生支持);(推荐)(即实现了PipelineAsCode也便于统一管理。)

    • 将Jenkinsfile 存放在制品库(需要第三方插件);(制品库上你改起来不太方便。例如一些场景,我们现在写好一些jenkinsfile,不需要子公司去改,那么我们可以把这个文件打成一个包放到制品库里面,同步给他们,然后在流水线里这么去配置。但是如果需要去改的话,那么就需要用到git,git更方便一点。)

2、Pipeline 语法类型

image-20230407074622164

  • 脚本式语法:

    • ​ 适合以Groovy代码的方式描述Pipeline; (对groovy的要求比较高;)

    • 很多功能特性都需要自行写代码实现; (例如后续写一些邮件告警,想要获取流水线状态,可能都需要自己去写代码实现。)

    • ​ 语法简单,没有相对固定的语法,直接写groovy代码;

  • 声明式语法:

    • ​ 语法简单, 固定的语法;

    • ​ 提供很多已经定义好的功能;(流水线成功失败捕获等等

    • 也可以通过script{} 嵌入脚本式语法

jenkins语法有两种类型, 脚本式、声明式语法; 脚本式语法基本上都是通过Groovy代码来进行编写的。声明式语法有一些现成的功能可以直接用,减少脚本式语法的复杂性。但是声明式语法也不是完美的,功能固定还是需要脚本式语法来进行扩展才能实现更加灵活的Pipeline。

最佳实践是声明式语法中通过script{}标签来嵌入脚本式代码。

==💘 实战:脚本式语法测试-2023.4.7(测试成功)==

  • 代码

image-20230407080031554

groovy
node("build01"){stage('Build'){echo 'Hello world'}stage('Test'){echo 'Hello world'}}
  • 构建

image-20230407080010546

==💘 实战:测试脚本式语法-2023.4.7(测试成功)==

  • 代码

image-20230407121741408

groovy
pipeline {agent anystages {stage('Build') {steps {echo 'Hello World'println("devops")}}stage('Test') {steps {echo 'Hello World'}} }}
  • 运行

image-20230407121950605

==💘 实战:声明式语法嵌入脚本式语法-2023.4.7(测试成功)==

  • 错误格式代码:

image-20230407123203731

groovy
pipeline {agent anystages {stage('Build') {steps {echo 'Hello World'println("devops")name ="RongMei"if(name =="RongMei"){println("true")}}}stage('Test') {steps {echo 'Hello World'}} }}

构建后,会报错的:

image-20230407122711717

  • 正确格式代码:

image-20230407123436607

groovy
pipeline {agent anystages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}}}}stage('Test') {steps {echo 'Hello World'}} }}

以上代码运行后是正常的:

image-20230407123416348

3、Pipeline开发工具

image-20230412055616825

image-20230407123812957

很多人看到Jenkins Pipeline的代码后,就已经被劝退了。 感觉代码的难度很高,其实难度并不高。利用好开发工具后面理解起来就更简单些。 选择任意pipeline类型的作业,点击“流水线语法”即可进入pipeline开发工具页面。

image-20230408085100210

1. 片段生成器

image-20230408085142996

image-20230408090652345

当你安装好插件之后,很多插件提供了对应的代码块。 我们可以导航到片段生成器中找到对应的代码块生成。如果没有找到相关的语法,可以检查是否安装配置了相关的插件。

这个工具可以帮助我们生成Pipeline的部分代码,降低Pipeline的开发难度。流水线代码片段生成器, 非常好用。在这里可以找到每个插件以及Jenkins内置的方法的使用方法。使用片段生成器可以根据个人需要生成方法,有些方法来源于插件,则需要先安装相关的插件才能使用哦。

范例:error报错

image-20240616160746465

修改代码:

image-20240616160823008

构建:

image-20240616160849884

image-20240616160907195

范例:利用片段生成器生成执行shell命令代码

==💘 实战:利用片段生成器生成执行shell命令代码-2023.4.7(测试成功)==

  • 利用片段生成器生成执行shell命令代码

image-20230408085328044

  • 代码

image-20230408085627114

groovy
pipeline {agent anystages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh 'ls -al'}}}stage('Test') {steps {echo 'Hello World'}} }}
  • 运行

image-20230408085440213

范例:单引号和双引号的区别

==💘 实战:单引号和双引号的区别-2023.4.7(测试成功)==

单引号里写变量是不生效的;(和其它编程语言差不多)

注意:这里一定要使用双引号,否则会把其当做字符串打印出的!(linux中单引号与双引号的区别)

双引号:

  • 代码

image-20230408090024425

groovy
pipeline {agent anystages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'}} }}
  • 运行

image-20230408090126426

单引号:

  • 代码

image-20230408090238579

groovy
pipeline {agent anystages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh '''echo ${name}ls -al'''}}}stage('Test') {steps {echo 'Hello World'}} }}
  • 运行:

image-20230408090312697

2. 声明式语法生成器

image-20230408090737971

声明式语法式特有的一套语法,如果声明式语法忘记了可以导航到声明式语法生成器生成对应的代码片段。

范例:生成阶段

image-20240616161513539

编写代码:

image-20240616161645677

构建:

image-20240616161709198

3. 全局变量参考

image-20230408091720527

常见的全局变量

全局变量

bash
pipelineenvparamscurrentBuildscm

有时我们会获取一些项目的参数来做数据处理, 此时可以通过Jenkins提供的内置变量来获取对应的关键信息。

例如:获取当前项目的名称、构建ID、作业URL等等信息。

bash
BUILD_NUMBERBUILD_IDBUILD_DISPLAY_NAMEJOB_NAMEEXECUTOR_NUMBERNODE_NAMEWORKSPACEJENKINS_HOMEJENKINS_URLBUILD_URLJOB_URLdisplayNamedescriptiondurationenv.branchName ="develop"env.commitID ="${UUID.randomUUID().toString()}"println(env.commitID)env.commitID ="${env.commitID.split("-")[0]}"println(env.commitID)currentBuild.displayName ="#${env.branchName}-${env.commitID}"currentBuild.description ="Trigger by user jenkins \nbranch:${env.branchName}"pipeline {agent {label "build"}stages{stage("test"){steps{script{echo "${BUILD_NUMBER}"echo "当前下载代码分支为: ${env.branchName}"}}}}}

运行效果:

image-20240616163615437

image-20240616163700274

全局变量定义并使用

结论:

例如 env.myName ="xyy",myName ="xyy"等语法属于groovy语法,如果直接定义在stages/stage/steps里会报错的,需要在scripts里定义,或者在pipeline{}外面定义。

在pipeline{}外面定义的是全局变量;

在scripts里定义的变量属于局部变量,加上env标识的话,就属于全局变量了;

1、定义在pipeline{}外面

==💘 实践:输出全局变量BUILD_ID和BUILD_URL(测试成功)-2023.4.8==

  • 代码

image-20230408093537366

groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"pipeline {agent anystages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} }}
  • 构建

image-20230408093516103

2、定义在scripts{}里面

  • 我们首先将全局变量的定义放在stage里面:

image-20220420075702149

groovy
pipeline{agent {node {label "build"}}options {skipStagesAfterUnstable()}stages{stage("CheckOut"){steps{env.myName ="xyy"script{println("获取代码")echo 'i love you ,xyy'echo "${BUILD_ID}"echo "${env.BUILD_ID}"echo "$BUILD_ID"echo "${myName}"}}}stage("Build"){steps{script{println("运行构建")}}}}post {always{script{println("流水线结束后,经常做的事情")}}success{script{println("流水线成功后,要做的事情")}}failure{script{println("流水线失败后,要做的事情")}}aborted{script{println("流水线取消后,要做的事情")}}}}

结果构建失败了:

image-20220420075636291

  • 此时,我们修改下代码,再把其放在script里面,看能否构建成功:

image-20220420080240591

bash
pipeline{agent{node{label"build"}}options{skipStagesAfterUnstable()}stages{stage("CheckOut"){steps{script{env.myName="xyy"echo"${myName}"println("获取代码")echo'i love you ,xyy'echo"${BUILD_ID}"echo"${env.BUILD_ID}"echo"$BUILD_ID"}}}stage("Build"){steps{script{println("运行构建")}}}}post{always{script{println("流水线结束后,经常做的事情")}}success{script{println("流水线成功后,要做的事情")}}failure{script{println("流水线失败后,要做的事情")}}aborted{script{println("流水线取消后,要做的事情")}}}}

image-20220420080225322

可以看到,本次构建成功,原来就是把命令式代码写在stage位置了,导致构建失败!因此也验证了上面的结论脚本式的语法我们都写在script里面

  • 刚才在检出代码阶段定义的全局变量,是否可以在构建阶段里面使用?(肯定可以的)这边来测试下

image-20220420080653894

bash
pipeline{agent{node{label"build"}}options{skipStagesAfterUnstable()}stages{stage("CheckOut"){steps{script{env.myName="xyy"echo"${myName}"env.branchName="dev"println("获取代码")echo'i love you ,xyy'echo"${BUILD_ID}"echo"${env.BUILD_ID}"echo"$BUILD_ID"}}}stage("Build"){steps{script{println("运行构建")echo"${branchName}"}}}}post{always{script{println("流水线结束后,经常做的事情")}}success{script{println("流水线成功后,要做的事情")}}failure{script{println("流水线失败后,要做的事情")}}aborted{script{println("流水线取消后,要做的事情")}}}}

image-20220420080729187

结论:可以看到,在某一个stage里定义的全局变量,在其他stage里也是可以使用的!(符合预期)

🍀 示例:如何使用命令式语法来定义局部变量

  • 代码
bash
pipeline{agent{node{label"build"}}stages{stage("CheckOut"){steps{script{println("获取代码")envType="test"}}}stage("Build"){steps{script{println("运行构建")echo"envType:${envType}"}}}}}

进行构建:

image-20230412143311392

结论:发现在script里定义的局部变量,在其他stage里也是可以使用的。。。😥并且,也是可以在stage里引用局部变量的,也是不会报错的。

  • Jenkins web也是可以配置全局变量的,但是不推荐(使用groovy代码就好)

管理Jenkins-配置系统:

image-20230622084806614

image-20230622084850879

4.调试回放流水线

image-20230408093800204

适合调试流水线代码,构建后点击回访可以看到上次构建运行的Pipeline代码,而我们可以通过此编辑器对代码进行修改和调试而不会影响原始的代码。

4、Pipeline核心语法

声明式+脚本式

image-20240616164534245

Pipeline核心语法1

pipeline{}

image-20230408094054613

声明式流水线的定义, 一个pipeline{}。

agent{}

image-20230408100953612

  • 定义Pipeline中的运行节点(Jenkins Agent)

  • pipeline{agent {} }流水线级别的节点

  • stage{agent{} }阶段级别的节点

  • 使用方式

    • label:**在特定的名称或者label节点**运行; (标签=分组)
      
    • any:在任意节点运行; 
      
    • none:当pipeline全局指定agent为none,则根据每个stage中定义的agent运行(stage必须指定)。
      
    • node:**支持自定义流水线的工作目录**。
      

pipeline里必须要有agent格式的。

groovy
pipeline {agent any }pipeline {agent {label "labelName或者节点名称"}}pipeline {agent none stages{stage('Build'){agent {label "build"} steps {echo "building......"}}}}pipeline {agent {node {label "labelName或者节点名称"customWorkspace "/opt/agent/workspace"}}}

Q:agent {node {label }}这个语法第一次见,怎么知道有这个语法,是声明语法生成器中的吗?

但是声明式语法生成器中是没有这个配置的。

范例:agent配置的几种方法

==💘 实践:agent配置的几种方法(测试成功)-2023.4.8==

⚠️ 特别注意:label后面可以接labelName或者节点名称,都是可以的。

测试过程如下:

  • 当前测试环境节点名称及标签如下:

image-20230408102331115

  • label后面可以接节点名称

代码:

image-20230408102439076

groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"pipeline {agent {label "build01"}stages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} }}

运行:

image-20230408102544526

  • label后面可以接labelName

代码:

image-20230408102612091

groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"pipeline {agent {label "build"}stages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} }}

image-20230408102653525

  • 作业运行在任意节点:

代码:

image-20230408102746227

groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"pipeline {agent anystages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} }}

运行:

image-20230408102832203

  • 使用node来自定义流水线构建目录

代码:

image-20230408102923728

groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"pipeline {agent {node{label "build"customWorkspace "/opt/jenkinsagent/workspace/test"}}stages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} }}

构建:

image-20230408103006298

  • 如果指定一个错误节点或者标签,测试的作业状态时什么样的呢?

代码:

image-20230408103402172

groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"pipeline {agent {node{label "build02"customWorkspace "/opt/jenkinsagent/workspace/test"}}stages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} }}

构建:

image-20230408103345416

image-20230408103443265

  • 测试:label虽然不支持正则,agent是可以加变量去选节点的

代码:

image-20230408110601473

groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"choiceBuildNode ="build"pipeline {agent {node{label "${choiceBuildNode}"customWorkspace "/opt/jenkinsagent/workspace/test"}}stages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} } }

运行:

image-20230408110534206

  • 运行在jenins节点

image-20240616213357643

image-20240616213304909

image-20240616212028492

stages{}

image-20230408104418979

定义Pipeline的阶段;

bash
pipeline{stages{}}stages>stage>steps
  • 关系: stages >stage >steps >script
  • 定义:
    • stages:包含多个stage阶段
    • stage:包含多个steps步骤
    • steps:包含一组特定的脚本(加上script后就可以实现在声明式脚本中嵌入脚本式语法了)
groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"pipeline {agent {node{label "build02"customWorkspace "/opt/jenkinsagent/workspace/test"}}stages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} }}

  • 注意:steps下是没有step的。

代码:

image-20230408161337707

groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"choiceBuildNode ="build"pipeline {agent {node{label "${choiceBuildNode}"customWorkspace "/opt/jenkinsagent/workspace/test"}}stages {stage('Build') {steps {step{echo "hello"}echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} } }

报错:

image-20230408161319014

⚠️ 注意:

  • 虽然有的shell命令放在steps里也不会报错的,但是为了代码的规范性及可读性,强烈建议将shell命令都放在script里!(有可能if else放在steps里可能会报错)
  • scripts里是存放groovy脚本的;

image-20220420072705011

image-20240616215803124

post{}

image-20230408105423408

  • 根据流水线的最终状态做一些操作

  • 状态:

    • always: 总是执行 (例如每次执行后清理缓存动作;)

    • success: 仅流水线成功后执行 (执行成功后,也可触发下一动作,例如触发CD;(远程构建))

    • failure: 仅流水线失败后执行 (failure/aborted:可能要给开发人员发个邮件。)

    • aborted: 仅流水线被取消后执行

    • unstable:不稳定状态,单测失败等

注意:post{}是和states同级的!

groovy
pipeline {..........post {always{script{println("流水线结束后,经常做的事情")}}success{script{println("流水线成功后,要做的事情")}}failure{script{println("流水线失败后,要做的事情")}}aborted{script{println("流水线取消后,要做的事情")}}}}

范例:综合脚本

==💘 实践:post{}测试(测试成功)-2023.4.8==

image-20230408110226859

  • 代码

image-20230408105817125

groovy
currentBuild.displayName ="Devops:commitID"currentBuild.description ="Branch:master"pipeline {agent {node{label "build"customWorkspace "/opt/jenkinsagent/workspace/test"}}stages {stage('Build') {steps {echo 'Hello World'println("devops")script{name ="RongMei"if(name =="RongMei"){println("true")}sh """echo ${name}ls -al"""}}}stage('Test') {steps {echo 'Hello World'echo"build_id:${BUILD_ID}"echo "build_url:${BUILD_URL}"}} }post {always{script{println("流水线结束后,经常做的事情")}}success{script{println("流水线成功后,要做的事情")}}failure{script{println("流水线失败后,要做的事情")}}aborted{script{println("流水线取消后,要做的事情")}}} }
  • 运行:

image-20230408105942304

Pipeline核心语法2

environment{}

image-20230408161647214

以声明式脚本语法的方式定义环境变量;

局部变量优先级高于全局变量;

推荐:声明式语法里使用enironment这个语句块来写。

方式1:声明式语法

定义: 通过键值对(k-v)格式定义流水线在运行时的环境变量, 分为流水线级别和阶段级别。

groovy
pipeline {agent anyenvironment {NAME="RongMei"VERSION="1.1.10"ENVTYPE="DEV"} stages {stage("build"){environment {VERSION="1.1.20"}steps {script {echo "${VERSION}"echo "${buildUser}"}}}}}

方式2:全局变量可以放在pipeline外面

groovy
env.lover="xyy"env.age=18pipeline {agent anyenvironment {NAME="RongMei"VERSION="1.1.10"ENVTYPE="DEV"} stages {stage("build"){environment {VERSION="1.1.20"}steps {script {echo "${VERSION}"echo "lover:${env.lover} age:${env.age}"}}}}}

image-20240617213646579


==💘 实践:变量测试(测试成功)-2023.4.8==

  • 代码

image-20230408200457069

groovy
buildUser ="jenkins"pipeline {agent anyenvironment {NAME="RongMei"VERSION="1.1.10"ENVTYPE="DEV"} stages {stage("build"){environment {VERSION="1.1.20"}steps {script {echo "${VERSION}"echo "${buildUser}"}}}}}
  • 运行

image-20230408200422720

options{}

image-20230408201331230

Pipeline运行时的一些选项

  • 设置保存最近的记录
  • 禁止并行构建
  • 跳过默认的代码检出
  • 设定流水线的超时时间(可用于阶段级别)
  • 设定流水线的重试次数(可用于阶段级别)
  • 设置日志时间输出(可用于阶段级别)

⚠️ 注意:

(以代码的方式定义的配置,需要流水线构建运行后才能看到效果)。

Jenkins需要加载一下,才能够做这个设置。

所以刚才我们定义的这些设置,都得初始化下。第一次初始化时,不用去关心它的状态是成功还是失败,它只是进行一些项目的初始化。

image-20230408201526495

常用配置:

groovy
## 设置保存最近的记录options {buildDiscarder(logRotator(numToKeepStr:'1')) }## 禁止并行构建options {disableConcurrentBuilds() }## 跳过默认的代码检出options {skipDefaultCheckout() }## 设定流水线的超时时间(可用于阶段级别)options {timeout(time:1,unit:'HOURS') }## 设定流水线的重试次数(可用于阶段级别)options {retry(3) }## 设置日志时间输出(可用于阶段级别)options {timestamps() }

groovy
pipeline {options {disableConcurrentBuilds()skipDefaultCheckout()timeout(time:1,unit:'HOURS')}stages {stage("build"){options {timeout(time:5,unit:'MINUTES')retry(3)timestamps()}}}}}

image-20230408201846465

image-20230408201904360


范例:option选项测试
groovy
pipeline {agent anyoptions {disableConcurrentBuilds()skipDefaultCheckout()timeout(time:1,unit:'HOURS')buildDiscarder logRotator(artifactDaysToKeepStr:'',artifactNumToKeepStr:'',daysToKeepStr:'30',numToKeepStr:'5')}stages {stage("build"){options {timeout(time:5,unit:'MINUTES')retry(3)timestamps()}steps{echo "hello"}}}}

范例:丢弃旧的构建

==💘 实践:options测试(测试成功)-2023.4.8==

  • 使用片段生成器生成代码

image-20230408202026247

默认这个流水线的配置这里为空:

image-20230408202213092

  • 代码

image-20230408202401996

groovy
buildUser ="jenkins"pipeline {agent anyoptions {buildDiscarder logRotator(artifactDaysToKeepStr:'',artifactNumToKeepStr:'',daysToKeepStr:'30',numToKeepStr:'5')} environment {NAME="RongMei"VERSION="1.1.10"ENVTYPE="DEV"} stages {stage("build"){environment {VERSION="1.1.20"}steps {script {echo "${VERSION}"echo "${buildUser}"}}}}}
  • 运行

image-20230408202257729

可以看到,运行流水线后,这里的配置被配置上了。

image-20230408202328242

范例:配置流水线跳过默认代码检出功能

💘 实践:配置流水线跳过默认代码检出功能-2023.6.26(测试成功)

  • 实验环境
bash
jenkins/jenkins:2.346.3-2-lts-jdk11gitlab/gitlab-ce:15.0.3-ce.0sonarqube:9.9.0-communitySonarScanner4.8.0.2856
  • 实验软件(无)

  • 当前现象

当给jenkins流水线配置了从git仓库拉取Jenkinsfile时(即使用共享库),编译阶段会多了一个默认代码检出阶段

image-20230626061053348

image-20230626061121243

image-20230626061234609

  • 那该如何跳过这个功能呢?

在声明式片段里生成语法下:

image-20230626061351314

groovy
options {skipDefaultCheckout true}
  • 我们来配置下共享库里的代码,提交,再次构建测试下

image-20230626061717927

提交。

再次构建测试:

image-20230626061624466

构建结果:

image-20230626061810886

符合预期,以上问题已解决。😘

parameters{}

image-20230408202952276

  • 参数化构建,在jenkinsfile中以代码的方式定义构建参数;
  • 注意由于是通过代码定义的,需运行一次构建后才能生成
  • String、Choice…

结论:

如果同时有environmentparameters时,env.VERSIONVERSION默认会使用enironment的值的,因此要想使用parameters,推荐使用params.VERSION来引用。

  • 定义: 流水线在运行时设置的参数,UI页面的参数。所有的参数都存储在params对象中。
  • 将web ui页面中定义的参数,以代码的方式定义。 (以代码的方式定义的配置,需要流水线构建运行后才能看到效果)
groovy
pipeline {agent anyparameters {string(name:'VERSION',defaultValue:'1.1.1',description:'') }stages {stage("Build"){steps {echo "${params.VERSION}"}}}}

范例:参数构建测试

==💘 实践:parameters测试(测试成功)-2023.4.8==

  • 使用片段生成器生成代码

image-20230408203554237

image-20230408203610827

  • 代码

image-20230408204206552

groovy
buildUser ="jenkins"pipeline {agent anyoptions {buildDiscarder logRotator(artifactDaysToKeepStr:'',artifactNumToKeepStr:'',daysToKeepStr:'30',numToKeepStr:'5')} parameters {choice choices:['prod','test','dev'],description:'Please choice env name.',name:'envName'string defaultValue:'1.1.1',name:'Version',trim:true}environment {NAME="RongMei"VERSION="1.1.10"ENVTYPE="DEV"} stages {stage("build"){environment {VERSION="1.1.20"}steps {script {echo "${VERSION}"echo "${buildUser}"echo "${params.envName}"echo "${env.envName}"echo "${envName}"}}}}}
  • 运行

image-20230408203931736

image-20230408204117656

Pipeline核心语法3

trigger{}

image-20230408205131493

bash
-cron定时触发:triggers{cron('H */7 * * 1-5') }(例如代码扫描。)-pollSCM:triggers{pollSCM('H */7 * * 1-5') }##被动地去检查你的代码库是否有更新,如果有更新就触发任务;

image-20230409070419804


范例:cron触发

==💘 实践:trigger测试(测试成功)-2023.4.8==

常见的触发方式:

image-20230408205449796

使用cron触发:

image-20230408205713818

默认trigger这里为空:

image-20230408220210643

  • 代码

image-20230408220610566

groovy
buildUser ="jenkins"pipeline {agent anyoptions {buildDiscarder logRotator(artifactDaysToKeepStr:'',artifactNumToKeepStr:'',daysToKeepStr:'30',numToKeepStr:'5')} parameters {choice choices:['prod','test','dev'],description:'Please choice env name.',name:'envName'string defaultValue:'1.1.1',name:'Version',trim:true}triggers {cron 'H ****'}environment {NAME="RongMei"VERSION="1.1.10"ENVTYPE="DEV"} stages {stage("build"){environment {VERSION="1.1.20"}steps {script {echo "${VERSION}"echo "${buildUser}"echo "${params.envName}"echo "${env.envName}"echo "${envName}"}}}}}
  • 运行

image-20230408220450123

可以看到,trigger这里出现了配置,符合预期。

image-20230408220425622

范例:上游项目构建触发
groovy
triggers {upstream 'demo2,'}

我们不会用这种方式来触发,会用一个比较通用的方式来触发的,请看后文。

  • 生成代码

image-20240618071439475

image-20240618071515059

groovy
buildUser ="jenkins"pipeline {agent anyoptions {buildDiscarder logRotator(artifactDaysToKeepStr:'',artifactNumToKeepStr:'',daysToKeepStr:'30',numToKeepStr:'5')} parameters {choice choices:['prod','test','dev'],description:'Please choice env name.',name:'envName'string defaultValue:'1.1.1',name:'Version',trim:true}triggers {upstream 'demo2,'}environment {NAME="RongMei"VERSION="1.1.10"ENVTYPE="DEV"} stages {stage("build"){environment {VERSION="1.1.20"}steps {script {echo "${VERSION}"echo "${buildUser}"echo "${params.envName}"echo "${env.envName}"echo "${envName}"}}}}}
  • 运行后,demo项目里就能看到,符合预期:

image-20240618071751631

input{}

image-20230409071232385

参数解析

  • message:提示信息
  • ok:表单中确认按钮的文本
  • submitter:提交人,默认所有人可以
  • parameters: 交互时用户选择的参数

小demo:

groovy
pipeline {agent anystages {stage('Deploy') {input {message "是否继续发布"ok "Yes"submitter "zeyang,aa"parameters {string(name:'ENVTYPE',defaultValue:'DEV',description:'env type..[DEV/STAG/PROD]')}}steps {echo "Deploy to ${ENVTYPE},doing......."}}}}

image-20240618073444988


==💘 实践:input测试(测试成功)-2023.4.8==

  • 使用声明式语法生成器生成代码

image-20230409071805539

image-20230409071818912

image-20230409071830287

  • 代码

image-20230409072814735

groovy
buildUser ="jenkins"pipeline {agent anyoptions {buildDiscarder logRotator(artifactDaysToKeepStr:'',artifactNumToKeepStr:'',daysToKeepStr:'30',numToKeepStr:'5')} parameters {choice choices:['prod','test','dev'],description:'Please choice env name.',name:'envName'string defaultValue:'1.1.1',name:'Version',trim:true}triggers {cron 'H ****'}environment {NAME="RongMei"VERSION="1.1.10"ENVTYPE="DEV"} stages {stage("build"){environment {VERSION="1.1.20"}input {message 'Please choice your options.'ok '提交'parameters {choice choices:['rollback','stop'],name:'runOptions'}}steps {script {echo "${VERSION}"echo "${buildUser}"echo "${params.envName}"echo "${env.envName}"echo "${envName}"echo "${runOptions}"if("${runOptions}"=="rollback"){println("rollback……")}if("${runOptions}"=="stop"){println("stop……")} }}}}}
  • 运行

选择rollback:

image-20230409072908555

image-20230409072929321

image-20230409072950748

选择stop:

image-20230409073044534

image-20230409073104669

  • 注意:

image-20230413064637483

when{}

image-20230409074107470

根据条件判断是否运行Stage;

判断条件

  • 根据环境变量判断
  • 根据表达式判断
  • 根据条件判断(not/allOf/anyOf)
groovy
pipeline {agent anystages {stage('Build') {steps {echo 'build......'}}stage('Deploy') {when {environment name:'DEPLOY_TO',value:'DEV'}steps {echo 'Deploying.......'}}}}### allOf 条件全部成立when {allOf {environment name:'CAN_DEPLOY',value:'true'environment name:'DEPLOY_ENV',value:'dev'}}### anyOf 条件其中一个成立when {anyOf {environment name:'CAN_DEPLOY',value:'true'environment name:'DEPLOY_ENV',value:'dev'}}

tstmp_20230409074231


范例:根据环境变量去配置
  • 代码:
groovy
pipeline {agent anystages {stage('Build') {steps {echo 'build......'}}stage('Deploy') {when {environment name:'DEPLOY_TO',value:'DEV'}steps {echo 'Deploying.......'}}}}

运行:(因为默认是没这个变量的,Deploy阶段肯定跳过的)

image-20240618074001311

image-20240618074018910

  • 添加DEPLOY_TO变量后,再次测试
groovy
pipeline {agent anyenvironment {DEPLOY_TO='DEV'}stages {stage('Build') {steps {echo 'build......'}}stage('Deploy') {when {environment name:'DEPLOY_TO',value:'DEV'}steps {echo 'Deploying.......'}}}}

再次运行:

image-20240618074136152

范例

==💘 实践:when测试(测试成功)-2023.4.8==

  • 代码

image-20230409075514494

groovy
buildUser ="jenkins"pipeline {agent anyoptions {buildDiscarder logRotator(artifactDaysToKeepStr:'',artifactNumToKeepStr:'',daysToKeepStr:'30',numToKeepStr:'5')} parameters {choice choices:['prod','test','dev'],description:'Please choice env name.',name:'envName'string defaultValue:'1.1.1',name:'Version',trim:true}triggers {cron 'H ****'}environment {NAME="RongMei"VERSION="1.1.10"ENVTYPE="DEV"} stages {stage("build"){environment {VERSION="1.1.20"}input {message 'Please choice your options.'ok '提交'parameters {choice choices:['rollback','stop'],name:'runOptions'}}steps {script {echo "${VERSION}"echo "${buildUser}"echo "${params.envName}"echo "${env.envName}"echo "${envName}"echo "${runOptions}"if("${runOptions}"=="rollback"){println("rollback……")}if("${runOptions}"=="stop"){println("stop……")} env.runOptions ="${runOptions}"}}}stage("Rollback"){when {environment name:"runOptions",value:'rollback'}steps {println("rollback……")}}}}
  • 运行

当选择rollback时:Rollback阶段被执行

image-20230409075614942

image-20230409075600645

image-20230409075642818

当选择stop时:Rollback阶段被跳过

image-20230409075331319

image-20230409075353348

image-20230409075304539

prallel{}

image-20230410053439916

Stage并行运行

场景: 自动化测试,多主机并行发布。

groovy
pipeline {agent anystages {stage('Parallel Stage') {failFast trueparallel {stage('windows') {agent {label "master"}steps {echo "windows"}}stage('linux') {agent {label "build"}steps {echo "linux"}}}}}}

tstmp_20230410053537


==💘 实践:parallel测试(测试成功)-2023.4.10==

  • 代码

image-20230410053958804

groovy
pipeline {agent anystages {stage('Parallel Stage') {failFast trueparallel {stage('windows') {agent {label "master"}steps {echo "windows"}}stage('linux') {agent {label "build"}steps {echo "linux"}}}}}}
  • 运行

image-20230410053923552

FAQ:如何解决并发构建中的workspace问题?

这个workspace问题挺重要的。(已解决)

多个并行阶段使用一个工作目录肯定是有问题的;(在每次构建的时候加一个随机数)

1.build_id

2.使用随机数

或者直接禁用并行构建方法也行;

image-20240618080618682

并行构建用到的场景:

情况1:如果一个项目管理多个微服务,那么就会需要用到并行构建; 情况2:多分支;

方法1:build_id

groovy
env.nworkspace ="/opt/agent/test/build-${BUILD_ID}"pipeline{agent{node{label "build"customWorkspace "${env.nworkspace}"}}stages{stage("build"){steps{echo "${env.nworkspace}"}}}}

多点击几次运行:

image-20240618080005846

image-20240618080115808

方法2:随机数

groovy
env.nworkspace ="/opt/agent/test/${JOB_NAME}-${UUID.randomUUID().toString()}"pipeline{agent{node{label "build"customWorkspace "${env.nworkspace}"}}stages{stage("build"){steps{echo "${env.nworkspace}"}}}}### 输出demo-fec54ca7-81a5-452e-91b5-2a187ab3562b

image-20240618080314145

  • 扩展:

2023.4.10-实践 - Jenkins 声明式管道中的动态并行阶段(简悦剪藏)

image-20230410055254149

二、Groovy

1、Groovy简介

groovy这一块我们基本只会用到数据处理;

使用groovy的目的:

  • 想让自己的pipeline更加灵活;
  • 搞微服务实践时,会调api,或者做数据处理;

image-20230413065952829

image-20230410061156284

Groovy功能强大,可选类型和动态语言(很多语法和python类似)天生支持Java平台

简洁且简单易学的语法。

可以与任何Java程序顺利集成、包括脚本编写功能、特定领域语言编写,运行时和编译时元编程以及函数式编程。

Groovy参考文档

http:centos7.6虚机

  • 实验软件

    链接:https:[root@devops ~]#ll -h apache-groovy-sdk-4.0.1.zip -rw-r--r--1rootroot57MApr2108:57apache-groovy-sdk-4.0.1.zip(2)解压[root@devops ~]#unzip apache-groovy-sdk-4.0.1.zip -d /usr/local/[root@devops ~]#cd /usr/local/groovy-4.0.1/[root@devops groovy-4.0.1]#lsbinconfdocgrooidlibLICENSElicensesNOTICEsrc[root@devops groovy-4.0.1]#cd bin/[root@devops bin]#lsgrapegroovy.batgroovy_completiongroovydocgroovyshjava2groovy.batgrape.batgroovycgroovyConsolegroovydoc.batgroovysh.batstartGroovygrape_completiongroovyc.batgroovyConsole.batgroovydoc_completiongroovysh_completionstartGroovy.batgroovygroovyc_completiongroovyConsole_completiongroovy.icojava2groovy[root@devops bin]#(3)设置环境变量[root@devops ~]#vim /etc/profile……exportGROOVY_HOME=/usr/local/groovy-4.0.1exportPATH=$JAVA_HOME/bin:$GROOVY_HOME/bin:$PATH[root@devops groovy-4.0.1]#source /etc/profile

  • 2、Groovy数据类型

    image-20230410063006631

    1.String

    字符串类型, 是在流水线中应用最为广泛的一种类型。

    字符串定义

    可以通过双引号、单引号、三引号定义;

    • 如果是普通字符串: 用单引号
    • 如果存在字符串插值(变量): 用双引号
    • 多引号:可以往里面放字符串片段。
    groovy
    Stringname ="zhangsan"Stringname ='zhangsan'Stringzeyang ="""devops"""println(zeyang)

    ⚠️ 注意:多引号里面可以对变量进行换行操作。

    image-20230624213345583

    等价于:

    image-20230624213550783

    字符串常见操作方法

    groovy
    name ="zeyang"pipeline {agent anystages{stage("run"){steps{script{println(name)job_name ="devops05-app-service_CI"println(job_name.indexOf("-"))bu_name =job_name.split('-')[0] println(bu_name) println(job_name.contains("CI"))println("size:${job_name.size()}")println("length:${job_name.length()}")println("enswith CI:${job_name.endsWith('CI')}")Stringnums ="1234567"println(nums.reverse()) Stringlog ="error:xxxxxx aa"println(log.minus("a")) println(log -"a") println(log +"a") println(log.plus("aa")) println(job_name.indexOf("-")) name ="xyy"defmessage ="hello ${name}"println(message) println(message.toString()) }}}}}

    ==💘 实战:groovy字符串测试-2023.4.10(测试成功)==

    • 代码

    image-20230410063435618

    groovy
    name ="zeyang"pipeline {agent anystages{stage("run"){steps{script{println(name)job_name ="devops05-app-service_CI"bu_name =job_name.split('-')[0]println(bu_name) println(job_name.contains("CI"))println("size:${job_name.size()}")println("length:${job_name.length()}")println("enswith CI:${job_name.endsWith('CI')}")}}}}}
    • 运行

    image-20230410063406654

    • 官方文档:

    image-20230410070115263

    2.List

    列表常见操作方法

    groovy
    tools =["gitlab","jenkins","maven","sonar"]pipeline {agent anystages{stage("run"){steps{script{listName =["hg","xyy","happy"]newListName =[1,2,3,4] asint[]println(listName)println(newListName)println(tools)println(tools +"k8s") println(tools <<"ansible") println(tools -"maven") println(tools)tools.add("maven") println(tools)println(tools.getClass())println(tools.contains("jenkins"))println(tools.size())println(tools[0])println(tools[-1])println(tools.isEmpty())println(tools.unique())println(tools.reverse())println(tools.sort())println(tools.count("jenkins"))}}}}}

    ==💘 实战:groovy列表测试-2023.4.10(测试成功)==

    • 代码

    image-20230410070617700

    groovy
    tools =["gitlab","jenkins","maven","sonar"]pipeline {agent anystages{stage("run"){steps{script{println(tools)println(tools +"k8s")println(tools)println(tools <<"ansible") println(tools)println(tools -"maven")println(tools)tools.add("maven")println(tools)println(tools.getClass())println(tools.contains("jenkins"))println(tools.size())println(tools[0])println(tools[-1])}}}}}
    • 运行

    image-20230410070637619

    • 官方文档:

    image-20230410070659399

    3.map

    map常见方法

    groovy
    user_info =["id":100,"name":"jenkins"]pipeline {agent anystages{stage("run"){steps{script{println(user_info)println(user_info["name"])println(user_info["id"])println(user_info.get("id")) user_info["name"] ="jenkinsX"println(user_info)println(user_info.containsKey("name"))println(user_info.containsValue(100))println(user_info.keySet())user_info.remove("name")println(user_info)}}}}}

    ==💘 实战:groovy字典测试-2023.4.10(测试成功)==

    • 代码

    image-20230410071337459·

    groovy
    user_info =["id":100,"name":"jenkins"]pipeline {agent anystages{stage("run"){steps{script{println(user_info)println(user_info["name"])println(user_info["id"])user_info["name"] ="jenkinsX"println(user_info)println(user_info.containsKey("name"))println(user_info.containsValue(100))println(user_info.keySet()) user_info.remove("name")println(user_info)}}}}}
    • 运行

    image-20230410071326270

    Groovy常用函数

    • 打印变量类型

    image-20230628075457515

    3、Groovy条件语句

    1.if语句

    groovy
    branchName ="dev"pipeline {agent anystages{stage("run"){steps{script {currentBuild.displayName =branchNameif(branchName =="dev"){println("deploy to dev....")currentBuild.description ="deploy to dev...."} elseif(branchName =="master"){println("deploy to stag....")currentBuild.description ="deploy to stag...."} else{currentBuild.description ="error..."println("error...")}}}}}}

    ==💘 实战:groovy if语句测试-2023.4.10(测试成功)==

    • 代码

    image-20230410072545433

    groovy
    branchName ="dev"pipeline {agent anystages{stage("run"){steps{script {currentBuild.displayName =branchNameif(branchName =="dev"){println("deploy to dev....")currentBuild.description ="deploy to dev...."} elseif(branchName =="master"){println("deploy to stag....")currentBuild.description ="deploy to stag...."} else{currentBuild.description ="error..."println("error...")}}}}}}
    • 运行

    image-20230410072533919

    2.switch语句

    groovy
    branchName ="dev"pipeline {agent anystages{stage("run"){steps{script {currentBuild.displayName =branchNameswitch(branchName) {case"dev":println("deploy to dev....")currentBuild.description ="deploy to dev...."breakcase"master":println("deploy to stag....")currentBuild.description ="deploy to stag...."breakdefault:currentBuild.description ="error..."println("error...")break}}}}}}

    ==💘 实战:groovy switch语句测试-2023.4.10(测试成功)==

    • 代码

    image-20230410072851279

    groovy
    branchName ="dev"pipeline {agent anystages{stage("run"){steps{script {currentBuild.displayName =branchNameswitch(branchName) {case"dev":println("deploy to dev....")currentBuild.description ="deploy to dev...."breakcase"master":println("deploy to stag....")currentBuild.description ="deploy to stag...."breakdefault:currentBuild.description ="error..."println("error...")break}}}}}}
    • 运行

    image-20230410072839175

    3.for循环

    groovy
    users =[["name":"zeyang","role":"dev"],["name":"zeyang1","role":"admin"],["name":"zeyang2","role":"ops"],["name":"zeyang3","role":"test"]]pipeline {agent anystages{stage("test"){steps{script{for(i=1;i<10;i++){println(i)} }}}stage("run"){steps{script {user_names =[]for(i inusers){println(i["name"])user_names <<i["name"]}println(user_names) 10.times {println('hello')}10.times {i->println(i)} }}}}}

    ==💘 实战:groovy for语句测试-2023.4.10(测试成功)==

    • 代码

    image-20230410073026444

    groovy
    users =[["name":"zeyang","role":"dev"],["name":"zeyang1","role":"admin"],["name":"zeyang2","role":"ops"],["name":"zeyang3","role":"test"]]pipeline {agent anystages{stage("run"){steps{script {user_names =[]for(i inusers){println(i["name"])user_names <<i["name"]}println(user_names) 10.times {println('hello')}10.times {i->println(i)}}}}}}
    • 运行

    image-20230410073104757

    4.while循环

    groovy
    sleeps =truepipeline {agent any stages{stage("run"){steps{script {while(sleeps){println("sleep....")}}}}}}

    ==💘 实战:groovy while语句测试-2023.4.10(测试成功)==

    • 代码
    groovy
    sleeps =truepipeline {agent any stages{stage("run"){steps{script {while(sleeps){println("sleep....")}}}}}}

    image-20230410073235411

    • 运行

    image-20230410073305305

    4、Groovy异常处理与函数

    1.异常处理

    image-20230410073956288

    try

    catch

    finally

    groovy
    pipeline{agent anystages{stage("run"){steps{script{try{println(a) } catch(Exceptione){println(e)} finally{println("always....")}}}}}}

    ==💘 实战:groovy 异常处理测试-2023.4.10(测试成功)==

    代码:

    groovy
    pipeline{agent anystages{stage("run"){steps{script{println(a) }}}}}

    运行:(肯定会报错的)

    image-20240618095131817

    加上异常处理代码后,再次运行:(就能看到会捕获并抛出异常,流水线执行成功,符合预期)

    groovy
    pipeline{agent anystages{stage("run"){steps{script{try{println(a) } catch(Exceptione){println(e)} finally{println("always....")}}}}}}

    image-20240618095247759

    2.函数

    image-20230410075122108

    函数定义

    函数传参

    函数返回值

    函数调用

    groovy
    users =[["id":1,"name":"jenkins1"],["id":2,"name":"jenkins2"],["id":3,"name":"jenkins3"],]pipeline{agent any stages{stage("run"){steps{script {name =GetUserNameByID(1)println(name) }}}}}defGetUserNameByID(id){for(i inusers){if(i["id"] ==id){returni["name"]}}return"null"}

    ==💘 实战:groovy 函数测试-2023.4.10(测试成功)==

    • 代码

    image-20230410075330365

    groovy
    users =[["id":1,"name":"jenkins1"],["id":2,"name":"jenkins2"],["id":3,"name":"jenkins3"],]pipeline{agent any stages{stage("run"){steps{script {name =GetUserNameByID(1)println(name) }}}}}defGetUserNameByID(id){for(i inusers){if(i["id"] ==id){returni["name"]}}return"null"}
    • 运行

    image-20230410075418144

    关于我

    我的博客主旨:

    • 排版美观,语言精炼;
    • 文档即手册,步骤明细,拒绝埋坑,提供源码;
    • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

    🍀 微信二维码 x2675263825 (舍得), qq:2675263825。

    image-20230107215114763

    🍀 微信公众号 《云原生架构师实战》

    image-20230107215126971

    🍀 语雀

    https:

    版权:此文章版权归 One 所有,如有转载,请注明出处!

    链接:可点击右上角分享此页面复制文章链接

    上次更新时间:

    最近更新